/*
@file: symTable.h
@author: ZZH
@time: 2021-12-27 15:27:54
@info: edl编译器符号表
*/
#pragma once
#include <map>
#include <string>

template <typename Symbol_t>
class SymTable_t
{
private:

protected:
    using SymTableStorge_t = std::map<const std::string, const Symbol_t>;
    SymTableStorge_t table;
public:
    using iterator = typename SymTableStorge_t::iterator;
    using const_iterator = typename SymTableStorge_t::const_iterator;
    using size_type = typename SymTableStorge_t::size_type;
    using difference_type = typename SymTableStorge_t::difference_type;
    using reverse_iterator = typename SymTableStorge_t::reverse_iterator;
    using const_reverse_iterator = typename SymTableStorge_t::const_reverse_iterator;

    SymTable_t() {};
    virtual ~SymTable_t()
    {
        for (auto it : this->table)
            delete it.second;
    }

    inline iterator begin() { return this->table.begin(); }
    inline iterator end() { return this->table.end(); }
    
    inline const_iterator begin() const { return this->table.begin(); }
    inline const_iterator end() const { return this->table.end(); }

    inline size_type size() { return this->table.size(); }
    inline size_type len() { return this->table.size(); }

    bool insert(const std::string& symName, const Symbol_t sym)
    {
        if (this->table.find(symName) != this->table.end())
            return false;
        this->table.insert({ symName, sym });
        return true;
    }
    
    bool remove(const std::string& symName)
    {
        auto it = this->table.find(symName);
        if (it != this->table.end())
        {
            this->table.erase(it);
            delete it->second;
            return true;
        }
        return false;
    }
    
    bool search(const std::string& symName, Symbol_t& sym) const
    {
        auto it = this->table.find(symName);
        if (it != this->table.end())
        {
            sym = it->second;
            return true;
        }
        return false;
    }
};

